"""
识别系统的service
病虫害预测模型
最后修改：3.29
修改人：陈泯全
"""
import requests
import numpy as np
import cv2
from flask import current_app
from utils.tools import process_imageNdarray,get_imageNdarrayFromNarray

class distinguishSevice():
    def __init__(self, modelIp='localhost'):
        self.CATEGORY_LIST = ["苹果-健康-无病", "苹果-黑心病-一般", "苹果-黑心病-严重", "苹果-灰斑病-一般", "苹果-雪松锈病-一般",
                              "苹果-雪松锈病-严重", "樱桃-健康-无病", "樱桃-白粉病-一般", "樱桃-白粉病-严重", "玉米-健康-无病",
                              "玉米-灰斑病-一般", "玉米-灰斑病-严重", "玉米-锈病-一般", "玉米-锈病-严重", "玉米-叶斑病-一般",
                              "玉米-叶斑病-严重", "玉米-花叶病毒病", "葡萄-健康-无病", "葡萄-黑腐病-一般", "葡萄-黑腐病-严重",
                              "葡萄-轮斑病-一般", "葡萄-轮斑病-严重", "葡萄-褐斑病-一般", "葡萄-褐斑病-严重", "柑桔-健康-无病",
                              "柑桔-黄龙病-一般", "柑桔-黄龙病-严重", "桃-健康-无病", "桃-疮痂病-一般", "桃-疮痂病-严重", "辣椒-健康-无病",
                              "辣椒-疮痂病-一般", "辣椒-疮痂病-严重", "马铃薯-健康-无病", "马铃薯-早疫病-一般", "马铃薯-早疫病-严重",
                              "马铃薯-晚疫病-一般", "马铃薯-晚疫病-严重", "草莓-健康-无病", "草莓-叶枯病-一般", "草莓-叶枯病-严重",
                              "番茄-健康-无病", "番茄-白粉病-一般", "番茄-白粉病-严重", "番茄-疮痂病-一般", "番茄-疮痂病-严重", "番茄-早疫病-一般",
                              "番茄-早疫病-严重", "番茄-晚疫病菌-一般", "番茄-晚疫病菌-严重", "番茄-叶霉病-一般", "番茄-叶霉病-严重",
                              "番茄-斑点病-一般", "番茄-斑点病-严重", "番茄-斑枯病-一般", "番茄-斑枯病-严重", "番茄红-蜘蛛损伤-一般",
                              "番茄-红蜘蛛损伤-严重", "番茄-黄化曲叶病毒病-一般", "番茄-黄化曲叶病毒病-严重", "番茄-花叶病毒病-一般"]
        # 模型推理URL
        self.SERVER_URL = 'http://{}:8501/v1/models/insect-classification:predict'.format(modelIp)
        # 模型状态URL
        self.SERVER_URL_STATUS = 'http://{}:8501/v1/models/insect-classification'.format(modelIp)
        # 模型输入输出信息URL
        self.SERVER_URL_METADATA = 'http://{}:8501/v1/models/insect-classification/metadata'.format(modelIp)

    """
    Tensorfing Serving请求模型
    返回值：
    status 预测状态
    predict_className 预测的结果类型
    predict_value 预测的概率
    time 花费的时间
    shape:[1, 229, 229, 3]
    """
    def serving(self, img):
        predict_request = '{"signature_name": "predict_images", "instances":%s }' % img.tolist()
        dict = {}
        try:
            response = requests.post(self.SERVER_URL, data=predict_request)
        except Exception as r:
            current_app.logger.error(r)
            dict['status'] = 0
            dict['value'] = -1
            dict['time'] = -1
            dict['species'] = '未知'
            dict['disease'] = '未知'
            dict['level'] = '未知'
            return dict
        time = response.elapsed.total_seconds()
        response.raise_for_status()
        # 获取预测结果
        predictions = response.json()['predictions']
        prediction_id = np.argmax(np.array(predictions))
        predict_value = np.max(np.array(predictions))
        predict_className = self.CATEGORY_LIST[prediction_id]
        predict = predict_className.split('-')
        dict['status'] = str(1)
        dict['value'] = str(predict_value)
        dict['time'] = str(time)
        dict['species'] = predict[0]
        dict['disease'] = predict[1]
        dict['level'] = predict[2]
        # current_app.logger.info('预测结果:{}'.format(dict))
        return dict

    """
    检测模型状态
    """
    def getStatus(self):
        # 测试模型状态
        reponse = requests.get(self.SERVER_URL_STATUS)
        print(reponse.content)
        # 获取模型输入\输出信息
        reponse = requests.get(self.SERVER_URL_METADATA)
        return reponse.content

    """
    测试模型
    """
    def test(self, imgdir):
        try:
            test = cv2.imread(imgdir)
        except Exception as r:
            current_app.logger.error(r)
            return 0, -1, -1
        if test.any() == None:
            current_app.logger.error('测试图片读取错误，路径{}'.format(imgdir))
            return 0,-1,-1
        testImg = get_imageNdarrayFromNarray(test)
        test1 = process_imageNdarray(testImg)
        predict_values = []
        times = []
        #warmup
        for i in range(1,10):
            dict = self.serving(test1)
            value = float(dict['value'])
            time = float(dict['time'])
            predict_values.append(value)
            times.append(time)

        means_predict_values = -1
        mean_times = -1
        means_predict_values = np.mean(predict_values)
        mean_times = np.mean(times)
        current_app.logger.info('模型状态：{}，平均值：{}，平均时间：{}'.format(1,means_predict_values,mean_times))
        return 1,means_predict_values, mean_times

